﻿using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using Model.LiveControl;
using Network;
using Network.Messages.LiveControl;
using Network.Messages.LiveControl.C2S;
using Network.Messages.LiveControl.S2C;
using Providers.LiveControl.Client;

namespace Managers.LiveControl.Client
{
    public sealed class LiveControlManager : Manager<LiveControlProvider>
    {
        public LiveControlManager(NetworkPeer network)
            : base(new LiveControlProvider(network))
        {
            Provider.OnScreenshotReceived += Provider_OnScreenshotReceived;
            Provider.OnRectChangeReceived += (s, e) => OnRectChangeReceived?.Invoke(s, e);
            Provider.OnProcessesReceived += (s, e) => OnProcessesReceived?.Invoke(s, e);
            Provider.OnRectesMessage += (s, e) => OnRectesMessage?.Invoke(s, e);

            Provider.OnWindowPickedevent += Provider_OnWindowPickedevent;
            Provider.OnPickedStatusChanged += (s, e) => OnPickedStatusChanged?.Invoke(s, e);

            Provider.OnSeverStatusReceived += (s, e) => OnSeverStatusReceived?.Invoke(s, e);
            Provider.OnResponseScreenRectReceived += Provider_OnResponseScreenRectReceived;

            Provider.OnCursorMessageEvent += Provider_OnCursorMessageEvent;
            Provider.OnServerShutdown += Provider_OnServerShutdown;

            Provider.OnFormListReceived += (s, e) => OnFormListReceived?.Invoke(s, e);
            Provider.OnFormItemUpdate += (s, e) => OnFormItemUpdate?.Invoke(s, e);
            Provider.OnReceivedFormMinisized += (s, e) => OnReceivedFormMinisized?.Invoke(s, e);
            Provider.OnReceivedFormClosed += (s, e) => OnReceivedFormClosed?.Invoke(s, e);

            Provider.OnReceivedRefuseControlMessage += Provider_OnReceivedRefuseControlMessage;
            Provider.OnReceivedRefuseControlApplyMessage += Provider_OnReceivedRefuseControlApplyMessage;

            Provider.OnReceivedGetControl += (s, e) => OnReceivedGetControl?.Invoke(s, e);
            Provider.OnReceivedLoseControl += (s, e) => OnReceivedLoseControl?.Invoke(s, e);
            Provider.OnReceivedRequestReCoverControlMessge += Provider_OnReceivedRequestReCoverControlMessge;

            network.OnDisconnected += Network_OnDisconnected;
        }

        private void Provider_OnReceivedRequestReCoverControlMessge(object sender, S2CRequestRecoverControlMessage e)
        {
            //2017年6月22日17:38:39
            OnReceivedRequestReCoverControlMessge?.Invoke(sender, e);
        }

        private void Provider_OnReceivedRefuseControlApplyMessage(object sender, S2CRefuseControlApplyMessage e)
        {
            OnReceivedRefuseControlApplyMessage?.Invoke(sender, e);
        }

        private void Provider_OnReceivedRefuseControlMessage(object sender, S2CRefuseControlMessage e)
        {
            OnReceivedRefuseControlMessage?.Invoke(sender, e);
        }

        private void Network_OnDisconnected(object sender, DisconnectedEventArgs e)
        {
            OnDisconnected?.Invoke(sender, e);
        }

        private void Provider_OnServerShutdown(object sender, KnowladgeServerMachineShutDown e)
        {
            OnServerShutdown?.Invoke(sender, e);
        }

        private void Provider_OnCursorMessageEvent(object sender, CursorMessage e)
        {
            OnCursorMessageEvent?.Invoke(sender, e);
        }
        private void Provider_OnScreenshotReceived(object sender, ScreenshotMessageEventArgs e)
        {
            OnScreenshotReceived?.Invoke(sender, e);
        }

        private void Provider_OnResponseScreenRectReceived(object sender, ResponseScreenRectMessage e)
        {
            OnResponseScreenRectReceived?.Invoke(sender, e);
        }

        private void Provider_OnWindowPickedevent(object sender, WindowPickedEventArgs e)
        {
            OnWindowPickedevent?.Invoke(sender, e);
        }

        public void NeedNewScreenshot()
        {
            Provider.FlagNeedNewScreen = true;
        }

        public void ClearConnection()
        {
            Network.DisconnectConnection();
            Provider.CurrentProcPtr = -1;
        }

        public void RequestScreenshot()
        {
            Provider.RequestScreenshot();
        }

        public event EventHandler<ScreenshotMessageEventArgs> OnScreenshotReceived;
        public event EventHandler<ServerStatusMessage> OnSeverStatusReceived;
        public event EventHandler<ResponseScreenRectMessage> OnResponseScreenRectReceived;
        public event EventHandler<KnowladgeServerMachineShutDown> OnServerShutdown;
        public event EventHandler<DisconnectedEventArgs> OnDisconnected;

        public event EventHandler<S2CResponseShareFormListMessage> OnFormListReceived;
        public event EventHandler<S2CTellClientFormItemUpdate> OnFormItemUpdate;
        public event EventHandler<S2CTellClientFormMinisizedMessage> OnReceivedFormMinisized;
        public event EventHandler<S2CTellClientFormClosedMessage> OnReceivedFormClosed;

        public event EventHandler<S2CRefuseControlMessage> OnReceivedRefuseControlMessage;
        public event EventHandler<S2CRefuseControlApplyMessage> OnReceivedRefuseControlApplyMessage;

        public event EventHandler<S2CRequestRecoverControlMessage> OnReceivedRequestReCoverControlMessge;
        public event EventHandler<S2CTellClientYouGetTheControl> OnReceivedGetControl;
        public event EventHandler<S2CTellClientYourControlBeRecoveredMessage> OnReceivedLoseControl;

        public void SetCurrentScreenIndex(int index)
        {
            Provider.CurrentScreenId = index;
        }
        #region 单窗口相关代码

        /// <summary>
        /// 设置当前被选取的服务端进程的ID
        /// </summary>
        /// <param name="id">如果没有选取任何进程，或者想显示整个窗口，请将访参数设置为-1</param>
        public void SetCurrentProcId(int id)
        {
            Provider.CurrentProcPtr = id;
        }

        public void ConnectToShareForm(FormItemModel model)
        {
            ResetScreenIndex();
            SetCurrentScreenIndex(model.ScreenIndex);
            SetCurrentProcId(model.Ptr.ToInt32());
            Provider.ConnectForm(model);
            RequestScreenshot();
            Provider.StartTick();

        }

        public bool FlagShowFullScreen => Provider.FlagShowFullScreen;

        /// <summary>
        /// 可用于异步请求服务端的进程列表
        /// </summary>
        /// <returns>异步完成后的结果</returns>
        public Task<ProcessesResponeMessageEventArgs> RequestProcListAsTask()
        {
            var tcs = RegisterAsTask(ref OnProcessesReceived);

            var childTask = Task.Factory.StartNew(() => { Provider.RequestProcList(); },
                TaskCreationOptions.AttachedToParent);

            return tcs.Task;
        }

        public event EventHandler<RectChangeMessageEventArgs> OnRectChangeReceived;
        public event EventHandler<ProcessesResponeMessageEventArgs> OnProcessesReceived;
        public event EventHandler<RectListResponeMessageEventArgs> OnRectesMessage;
        public event EventHandler<WindowPickedEventArgs> OnWindowPickedevent;
        public event EventHandler<WindowPickedStatus> OnPickedStatusChanged;
        public event EventHandler<CursorMessage> OnCursorMessageEvent;


        #endregion

        #region 鼠标事件

        public void NotifyGetWindow(CoustomMouseEventArgs coustomMouseEventArgs)
        {
            Provider.NotifyGetWindow(coustomMouseEventArgs);
        }

        public void NotifyMouseClick(CoustomMouseEventArgs mouseEventArgs)
        {
            Provider.NotifyMouseClick(mouseEventArgs);
        }

        public void NotifyMouseMove(CoustomMouseEventArgs mouseEventArgs)
        {
            Provider.NotifyMouseMove(mouseEventArgs);
        }

        public void NotifyMouseDoubleClick(CoustomMouseEventArgs mouseEventArgs)
        {
            Provider.NotifyMouseDoubleClick(mouseEventArgs);
        }

        public void NotifyMouseDown(CoustomMouseEventArgs coustomMouseEventArgs)
        {
            Provider.NotifyMouseDown(coustomMouseEventArgs);
        }

        public void NotifyMouseUp(CoustomMouseEventArgs coustomMouseEventArgs)
        {
            Provider.NotifyMouseUp(coustomMouseEventArgs);
        }

        public void NotifyMouseWheel(CoustomMouseEventArgs coustomMouseEventArgs)
        {
            Provider.NotifyMouseWheel(coustomMouseEventArgs);
        }

        #endregion

        #region 键盘事件

        public void NotifyKeyDown(KeyEventArgs keyEventArgs)
        {
            Provider.NotifyKeyDown(new KeyDownMessage { KeyEventArgs = keyEventArgs });
        }

        public void NotifyKeyPress(KeyPressEventArgs keyPressEventArgs)
        {
            Provider.NotifyKeyPress(new KeyPressMessage { KeyPressEventArgs = keyPressEventArgs });
        }

        public void NotifyKeyUp(KeyEventArgs keyEventArgs)
        {
            Provider.NotifyKeyUp(new KeyUpMessage { KeyEventArgs = keyEventArgs });
        }

        #endregion

        public void ResetScreenIndex()
        {
            Provider.ResetScreenIndex(0);
        }

        public void RequstFormList()
        {
            Provider.RequstFormList();
        }

        public void RequsetControlByForce()
        {
            Provider.RequsetControlByForce();
        }

        public void RequestControlByApply()
        {
            Provider.RequestControlByApply();
        }

        public void SendResultMessage(C2SResponseControlResultMessge tMessage)
        {
            Provider.SendResultMessage(tMessage);
        }

        public void ReshowShareForm(FormItemModel formItemModel)
        {
            Provider.ReshowShareForm(formItemModel);
        }

        public void Minimize()
        {
            if (Provider.CurrentProcPtr > 0)
            {
                var tMessage = new C2SChangeWindowStatusMessage
                {
                    Ptr = Provider.CurrentProcPtr,
                    Status = WindowShowType.Nomal
                };
                Provider.SendChangeWindowMessage(tMessage);
            }
        }

        public void Maximinze()
        {
            if (Provider.CurrentProcPtr > 0)
            {
                var tMessage = new C2SChangeWindowStatusMessage
                {
                    Ptr = Provider.CurrentProcPtr,
                    Status = WindowShowType.Max
                };
                Provider.SendChangeWindowMessage(tMessage);
            }
           
        }
    }
}